﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Web;
using System.Threading;
using System.Text.RegularExpressions;
using FatusoAction.Model;
using System.Collections.Specialized;
using System.Configuration;
using System.Xml.Linq;

namespace FatusoAction
{
    public class LegendaAction
    {
        #region [Recupera Listas de Legendas]

        public static List<LegendaModel> RecuperaLegenda(TipoVideo tipo, TituloModel titulo, int maxContadorLegenda, LegendaIdioma idioma, 
            LegendaFonte legendaFonte, bool silent)
        {
            List<LegendaModel> retorno = new List<LegendaModel>();
            try
            {
                #region [Legendas.TV]
                #region [Opções de Idioma]
                /*
                    <option value="1">Português-BR</option>
                    <option value="2">Inglês</option>
                    <option value="3">Espanhol</option>
                    <option value="10">Português-PT</option>
                    <option value="5">Alemão</option>
                    <option value="4">Francês</option>
                    <option value="16">Italiano</option>
                    <option value="6">Japonês</option>
                 */
                #endregion

                if (legendaFonte == LegendaFonte.Todos || legendaFonte == LegendaFonte.LTV)
                {

                    if (maxContadorLegenda > 0)
                    {
                        try
                        {
                            if (!silent) Console.WriteLine(">Procurando Legendas em Legendas.tv ...");
                            if (idioma == LegendaIdioma.Todos || idioma == LegendaIdioma.BR)
                            {
                                List<LegendaModel> retornoTemp = RecuperaLegenda_LegendasTV(tipo, titulo, maxContadorLegenda, LegendaIdioma.BR, silent);
                                retorno.AddRange(retornoTemp);
                                maxContadorLegenda = maxContadorLegenda - retornoTemp.Count;
                            }

                            if (maxContadorLegenda > 0 && (idioma == LegendaIdioma.Todos || idioma == LegendaIdioma.EN))
                            {
                                List<LegendaModel> retornoTemp = RecuperaLegenda_LegendasTV(tipo, titulo, maxContadorLegenda, LegendaIdioma.EN, silent);
                                retorno.AddRange(retornoTemp);
                                maxContadorLegenda = maxContadorLegenda - retornoTemp.Count;
                            }
                        }
                        catch (Exception) { }
                    }
                }
                #endregion

                #region [PODNAPISI]

                if (legendaFonte == LegendaFonte.Todos || legendaFonte == LegendaFonte.PNP)
                {
                    if (maxContadorLegenda > 0)
                    {
                        List<LegendaModel> legendasPNP = new List<LegendaModel>();
                        try
                        {
                            if (!silent) Console.WriteLine(">Procurando Legendas em Podnapisi ...");
                            legendasPNP = RecuperaLegenda_Podnapisi(tipo, titulo, maxContadorLegenda, idioma, silent);
                            retorno.AddRange(legendasPNP);
                            maxContadorLegenda = maxContadorLegenda - legendasPNP.Count;
                        }
                        catch (Exception) { }
                    }
                }
                
                #endregion

            }
            catch (Exception) { /*LogErro*/ }
            return retorno;
        }

        public static List<LegendaModel> RecuperaLegenda_LegendasTV(TipoVideo tipoVideo, TituloModel titulo, int maxContadorLegenda, LegendaIdioma idioma, bool silent)
        {
            string nomeRelease = titulo.Release;
            try
            {
                int idIdioma = 1;
                switch (idioma)
                {
                    case LegendaIdioma.BR:
                        idIdioma = 1;
                        break;
                    case LegendaIdioma.EN:
                        idIdioma = 2;
                        break;
                    default:
                        break;
                }

                string termoUri = Uri.EscapeDataString(nomeRelease);
                //string url_busca = "http://legendas.tv/legenda/busca/" + termoUri + "/id_idioma:" + idIdioma;
                string url_busca = "http://legendas.tv/legenda/busca/" + termoUri + "/" + idIdioma;
                HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url_busca);
                myRequest.Method = "GET";

                WebResponse myResponse = myRequest.GetResponse();
                StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
                string result = sr.ReadToEnd();
                sr.Close();
                myResponse.Close();

                string pattern = "<a href=\"/download/";
                var regex = new Regex(pattern, RegexOptions.IgnoreCase);

                List<LegendaModel> legendas = new List<LegendaModel>();
                MatchCollection matches = regex.Matches(result);
                if (matches.Count == 0) return legendas;

                int contador = 1;
                foreach (Match match in matches)
                {
                    try
                    {
                        string tempMatch = result.Substring(match.Index).Replace(pattern, "");

                        //Recupera Download URL
                        int index = tempMatch.IndexOf('/');
                        string codigoArquivo = tempMatch.Substring(0, index).Trim();

                        //Recupera Nome do Release
                        index = tempMatch.IndexOf('>');
                        tempMatch = tempMatch.Substring(index + 1);
                        index = tempMatch.IndexOf('<');
                        string release = tempMatch.Substring(0, index).Replace("\\", "_").Replace("/", "_");

                        if (FolderAndXMLAction.SerieEquivalente(nomeRelease, release, tipoVideo))
                        {
                            //Recupera Número de Downloads
                            tempMatch = tempMatch.Substring(index + 1);
                            index = tempMatch.IndexOf("<p class=\"data\">");
                            tempMatch = tempMatch.Substring(index + 16);
                            index = tempMatch.IndexOf(" download");

                            string numeroDownloads = tempMatch.Substring(0, index);

                            LegendaModel legendaModel = new LegendaModel();
                            legendaModel.Tipo = tipoVideo;
                            legendaModel.Fonte = LegendaFonte.LTV;
                            //legendaModel.Codigo = codigoArquivo;
                            legendaModel.NumeroDownloads = Convert.ToInt32(numeroDownloads);
                            legendaModel.Release = release;
                            legendaModel.NomePastaSerie = FolderAndXMLAction.RecuperaNomePastaVideo(release, tipoVideo);
                            legendaModel.Idioma = idioma;
                            legendaModel.DownloadURL = "http://legendas.tv/downloadarquivo/" + codigoArquivo;
                            legendas.Add(legendaModel);

                            if (contador >= maxContadorLegenda) break;
                            contador++;
                        }
                    }
                    catch (Exception) { }
                }

                return legendas;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public static List<LegendaModel> RecuperaLegenda_Podnapisi(TipoVideo tipoVideo, TituloModel titulo, int maxContadorLegenda, LegendaIdioma idioma, bool silent)
        {
            //http://www.podnapisi.net/en/ppodnapisi/search/sM/449830/sTS/1/sTE/2/sS/downloads/sO/desc

            //string nomeSerie = "";
            //string numTemporada = "";
            //string numEpisodio = "";
            //string idPodnapisi = "";

            #region [OLD_Recupera Dados da Série para Podnapisi]
            /*
            //Recupera Nome
            string releaseFiltro = FolderAndXMLAction.FiltraCaracteres(nomeRelease, false);
            List<string> listaRegex = new List<string>(){ 
                @"S\d+",        //S00E00
                @"S\d+E\d+",    //S00
                @"\d+X\d+" };   //00x00

            int indexMatch = -1;
            foreach (string regex in listaRegex)
            {
                Match match = Regex.Match(releaseFiltro.ToUpper(), regex);
                if (match.Success)
                {
                    indexMatch = match.Index;
                    break;
                }
            }
            nomeSerie = releaseFiltro.Substring(0, indexMatch).Trim();
            idPodnapisi = FolderAndXMLAction.RecuperaIdPodnapisi(nomeSerie);

            if (idPodnapisi == "")
            {
                if (!silent) Console.WriteLine(">Download via podnapisi não encontrou ID da série.");
                return new List<LegendaModel>();
            }

            //Recupera Temporada e Episodio
            Match match2 = Regex.Match(releaseFiltro.ToUpper(), @"S\d+");
            if (match2.Success)
            {
                numTemporada = match2.Groups[0].Value.ToUpper().TrimStart('S');
                int indexMatch2 = match2.Index;
                string tempEpiRls = "";
                if (indexMatch2 > 0) tempEpiRls = releaseFiltro.Substring(indexMatch2);

                Match match3 = Regex.Match(tempEpiRls.ToUpper(), @"E\d+");
                if (match3.Success)
                {
                    numEpisodio = match3.Groups[0].Value.ToUpper().TrimStart('E');
                }
            }
            else
            {
                Match match4 = Regex.Match(releaseFiltro.ToUpper(), @"\d+X\d+");
                if (match4.Success)
                {
                    int indexGroup = match4.Groups[0].Value.ToUpper().IndexOf('X');
                    numTemporada = match4.Groups[0].Value.ToUpper().Substring(0, indexGroup);
                    numEpisodio = match4.Groups[0].Value.ToUpper().Substring(indexGroup).TrimStart('X');
                }
                else
                {
                    Console.WriteLine(">Download via Podnapisi não reconheceu formato do Release.");
                    return new List<LegendaModel>();
                }
            }
            */
            #endregion

            try
            {
                string nomeRelease = titulo.Release;
                string termoUri = 
                    tipoVideo == TipoVideo.Filme ? 
                    Uri.EscapeDataString(titulo.NomeFilmeOuSerie + " (" + titulo.AnoOuTagEpisodio + ")") : 
                    Uri.EscapeDataString(nomeRelease);

                //string url_busca = "http://www.podnapisi.net/en/ppodnapisi/search/sM/" + idPodnapisi + "/sTS/" + numTemporada + "/sTE/" + numEpisodio + "/sS/downloads/sO/desc";
                string url_busca = "http://www.podnapisi.net/en/ppodnapisi/search/sK/" + termoUri + "/sS/downloads/sO/desc";
                HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url_busca);
                myRequest.Method = "GET";

                WebResponse myResponse = myRequest.GetResponse();
                StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
                string result = sr.ReadToEnd();
                sr.Close();
                myResponse.Close();

                //string pattern = @"class=\""release\""";
                string pattern = @"subtitle_page_link";
                var regex = new Regex(pattern, RegexOptions.IgnoreCase);

                List<LegendaModel> legendas = new List<LegendaModel>();
                MatchCollection matches = regex.Matches(result);
                if (matches.Count == 0) return legendas;

                int contador = 1;
                foreach (Match match in matches)
                {
                    int index;
                    string tempMatch = result.Substring(match.Index).Replace(pattern, "");

                    #region [Recupera URL]

                    //Recupera Download URL
                    //index = tempMatch.IndexOf("subtitle_page_link");
                    //tempMatch = tempMatch.Substring(index + 18);
                    index = tempMatch.IndexOf("href");
                    tempMatch = tempMatch.Substring(index + 6);

                    int indexDownURL = tempMatch.IndexOf('>');
                    string downloadURL = "http://www.podnapisi.net" + tempMatch.Substring(0, indexDownURL - 1);

                    #endregion

                    #region [Verifica Idioma]
                    //Recupera Idioma
                    //Recupera Nome do Release
                    LegendaIdioma idiomaLegenda = LegendaIdioma.BR;
                    string tempMatchIdioma = tempMatch;
                    int indexIdioma = tempMatchIdioma.IndexOf("\"flag\"");
                    tempMatchIdioma = tempMatchIdioma.Substring(indexIdioma + 4);
                    indexIdioma = tempMatchIdioma.IndexOf("title=");
                    tempMatchIdioma = tempMatchIdioma.Substring(indexIdioma + 6);

                    bool IdiomaValido = false;
                    if (idioma == LegendaIdioma.Todos || idioma == LegendaIdioma.BR)
                    {
                        if (tempMatchIdioma.Substring(0, 50).ToUpper().Contains("BRASILEIRO"))
                        {
                            idiomaLegenda = LegendaIdioma.BR;
                            IdiomaValido = true;
                        }
                    }
                    if (!IdiomaValido && (idioma == LegendaIdioma.Todos || idioma == LegendaIdioma.EN))
                    {
                        if (tempMatchIdioma.Substring(0, 50).ToUpper().Contains("ENGLISH"))
                        {
                            idiomaLegenda = LegendaIdioma.EN;
                            IdiomaValido = true;
                        }
                    }
                    #endregion

                    if (IdiomaValido) //Continua a Execução
                    {
                        #region [Recupera Dados do Release]

                        //Recupera Releases
                        List<string> releases = new List<string>();

                        index = tempMatch.IndexOf("html_title");
                        tempMatch = tempMatch.Substring(index + 12);
                        if (tempMatch.StartsWith("For downloads links in lists you need a premium account."))
                        {
                            releases.Add(nomeRelease);
                        }
                        else
                        {
                            index = tempMatch.IndexOf('\n');
                            string intervaloReleases = tempMatch.Substring(0, index);
                            intervaloReleases = intervaloReleases.Replace("<br/>", "$").Replace("<br />", "$").Replace("\\\">", "");

                            index = intervaloReleases.IndexOf("</span>");
                            if (index > 0)
                                intervaloReleases = intervaloReleases.Substring(0, index);
                            releases = intervaloReleases.Split('$').Distinct().ToList();
                        }

                        if (releases.Count > 0)
                        {
                            for (int i = 0; i < releases.Count; i++)
                            {
                                if (releases[i].EndsWith(">"))
                                    releases[i] = releases[i].Substring(0, releases[i].Length - 2);
                            }
                            releases.RemoveAll(r => r.EndsWith("..."));

                            if (FolderAndXMLAction.SerieEquivalente(nomeRelease, releases[0], tipoVideo))
                            {
                                //Número de Downloads
                                index = tempMatch.IndexOf("sort_column");
                                tempMatch = tempMatch.Substring(index + 13);
                                index = tempMatch.IndexOf("<");
                                string numDownStr = tempMatch.Substring(0, index);
                                tempMatch = tempMatch.Substring(index + 1);

                                string nomePasta = FolderAndXMLAction.RecuperaNomePastaVideo(releases[0], tipoVideo);
                                foreach (string release in releases)
                                {
                                    LegendaModel legendaModel = new LegendaModel();
                                    legendaModel.Tipo = tipoVideo;
                                    legendaModel.Fonte = LegendaFonte.PNP;
                                    //legendaModel.Codigo = "";
                                    legendaModel.NumeroDownloads = Convert.ToInt32(numDownStr);
                                    legendaModel.Release = release;
                                    legendaModel.NomePastaSerie = nomePasta;
                                    legendaModel.Idioma = idiomaLegenda;
                                    legendaModel.DownloadURL = downloadURL;
                                    legendas.Add(legendaModel);
                                }

                                if (contador >= maxContadorLegenda) break;
                                contador++;
                            }
                        }
                        #endregion
                    }

                }

                #region [Trata Repetições]

                List<int> idsVerificados = new List<int>();
                List<LegendaModel> legendasRetorno = new List<LegendaModel>();
                for (int i = 0; i< legendas.Count; i++)
                {
                    if(!idsVerificados.Contains(legendas.IndexOf(legendas[i])))
                    {
                        string url = legendas[i].DownloadURL;
                        legendasRetorno.Add(legendas[i]);

                        for (int j = i + 1; j < legendas.Count; j++)
                        {
                            string url2 = legendas[j].DownloadURL;
                            if(url2.ToUpper() == url.ToUpper())
                            {
                                idsVerificados.Add(legendas.IndexOf(legendas[j]));
                                string urlTemp = legendas[j].Release;
                                urlTemp = urlTemp.Replace('-', '.');
                                string[] urlTempSplit = urlTemp.Split('.');

                                legendas[i].Release += "(" + urlTempSplit[urlTempSplit.Length - 2] + "." + urlTempSplit[urlTempSplit.Length - 1] + ")";
                            }
                        }
                    }
                }

                //legendas = legendas.GroupBy(x => new { x.Fonte, x.DownloadURL }).Select(g => g.First()).ToList();

                #endregion

                return legendasRetorno;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region [Download de Legendas]

        public static void DownloadLegenda(LegendaModel legenda, TituloModel titulo)
        {
            switch (legenda.Fonte)
            {
                case LegendaFonte.LTV:
                    DownloadLegenda_LegendasTV(legenda, titulo);
                    break;
                case LegendaFonte.PNP:
                    DownloadLegenda_Podnapisi(legenda, titulo);
                    break;
                default:
                    break;
            }
        }

        public static void DownloadLegenda_LegendasTV(LegendaModel legenda, TituloModel titulo)
        {
            string releaseComando = titulo.Release;
            string downloadurl = legenda.DownloadURL;// "http://legendas.tv/downloadarquivo/" + legenda.Codigo;

            using (var client = new WebClient())
            {
                var values = new NameValueCollection();
                byte[] result2 = client.UploadValues(downloadurl, values);
                int indexFile = 0;
                string extension = "";

                string contentDisposition = client.ResponseHeaders["content-disposition"];
                indexFile = contentDisposition.IndexOf('.');
                if (contentDisposition != null && indexFile > 0)
                {
                    extension = contentDisposition.Substring(indexFile);
                    indexFile = extension.IndexOf("\"");
                    extension = extension.Substring(0, indexFile);
                }
                else
                {
                    contentDisposition = client.ResponseHeaders["Content-Type"];
                    indexFile = contentDisposition.IndexOf('/');
                    extension = "." + contentDisposition.Substring(indexFile + 1);
                    extension = extension.Replace("plain", "zip").Replace("octet-stream", "rar");
                }

                string caminhoDownload = ConfigurationSettings.AppSettings["CaminhoDownloadSerie"].TrimEnd('\\');
                caminhoDownload += "\\" + legenda.NomePastaSerie;
                if (legenda.Tipo == TipoVideo.Filme) caminhoDownload += "\\" + releaseComando;

                if (!Directory.Exists(caminhoDownload)) Directory.CreateDirectory(caminhoDownload);

                caminhoDownload += "\\" + legenda.Fonte.ToString().ToUpper() + "_" + legenda.Idioma.ToString().ToUpper() + "_" + legenda.Release + "_" + 
                    DateTime.Now.ToString("yyyyMMddHHmmss") + extension;
                File.WriteAllBytes(caminhoDownload, result2);
            }
        }

        private static void DownloadLegenda_Podnapisi(LegendaModel legenda, TituloModel titulo)
        {
            string releaseComando = titulo.Release;
            string downloadurl = legenda.DownloadURL;

            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(downloadurl);
            myRequest.Method = "GET";
            WebResponse myResponse = myRequest.GetResponse();
            StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
            string result = sr.ReadToEnd();
            sr.Close();
            myResponse.Close();


            string pattern = "button big download";
            var regex = new Regex(pattern, RegexOptions.IgnoreCase);
            
            List<LegendaModel> legendas = new List<LegendaModel>();
            MatchCollection matches = regex.Matches(result);
            string tempMatch = result.Substring(matches[0].Index + 27);
            int index = tempMatch.IndexOf('"');
            tempMatch = tempMatch.Substring(0, index);

            string arquivourl = "http://www.podnapisi.net" + tempMatch;

            using (var client = new WebClient())
            {
                var values = new NameValueCollection();
                byte[] result2 = client.UploadValues(arquivourl, values);

                string contentDisposition = client.ResponseHeaders["Content-Type"];
                int indexFile = contentDisposition.IndexOf('/');
                string extension = contentDisposition.Substring(indexFile).Replace('/', '.');
                //indexFile = extension.IndexOf("\"");
                //extension = extension.Substring(0, indexFile);

                string caminhoDownload = ConfigurationSettings.AppSettings["CaminhoDownloadSerie"].TrimEnd('\\');
                caminhoDownload += "\\" + legenda.NomePastaSerie;
                if (legenda.Tipo == TipoVideo.Filme) caminhoDownload += "\\" + releaseComando;

                if (!Directory.Exists(caminhoDownload)) Directory.CreateDirectory(caminhoDownload);

                caminhoDownload += "\\" + legenda.Fonte.ToString().ToUpper() + "_" + legenda.Idioma.ToString().ToUpper() + "_" + legenda.Release + "_" + 
                    DateTime.Now.ToString("yyyyMMddHHmmss") + extension;
                File.WriteAllBytes(caminhoDownload, result2);
            }
        }
        #endregion
    }
}
